package com.chris.core.socket.netty.handler;

import com.chris.core.socket.netty.dto.NettyAttributeMapDTO;
import com.chris.core.socket.netty.dto.SocketChannelMapDTO;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.Attribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.UUID;

import static com.chris.core.socket.netty.util.NettyRunTimeUtil.*;
import static com.chris.core.socket.netty.util.NettyRunTimeUtil.SocketChannelMap;

/**
 * WebSocket 处理器
 *
 * TextWebSocketFrame 类型， web socket 文本帧
 */
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        NettyAttributeMapDTO dto= getAttribute(ctx.channel());
        ctx.channel().writeAndFlush(new  TextWebSocketFrame("服务端已经收到消息:"+msg.text()));
        log.debug("服务器->收客户端["+dto.getId()+"] 消息"+msg.text());
    }

    /**
     * 新增客户端链接
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
       // channel.writeAndFlush("收到服务器内容");
        //--------------处理Attribute-------------------
        Attribute<NettyAttributeMapDTO> attr = channel.attr(NETTY_CHANNEL_KEY);
        NettyAttributeMapDTO attribute = attr.get();
        if (attribute == null) {
            String uuid = UUID.randomUUID().toString();
            //------------放入Attribute
            NettyAttributeMapDTO dto = new NettyAttributeMapDTO(uuid,"NettyWebSocket");
            attribute = attr.setIfAbsent(dto);
            //-------------放入ChannelMap
            SocketChannelMapDTO socketChannelMap = new SocketChannelMapDTO(uuid,"NettyWebSocket", channel);
            SocketChannelMap.put(uuid, socketChannelMap);
            //--------------
            addOnlineCount();
            log.debug("客户端["+uuid+"]新增 地址："+channel.remoteAddress()+ " 总客户端数："+getOnlineCount());
        } else {

        }
        //----------------------------------------------------

    }

    /**
     * channel被移除
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        // super.handlerRemoved(ctx);
        NettyAttributeMapDTO attribute=getAttribute(ctx.channel());
        if (attribute != null) {
            SocketChannelMap.remove(attribute.getId());
            subOnlineCount();
            log.debug("客户端["+attribute.getId()+"]离开 地址："+ctx.channel().remoteAddress()+ " 总客户端数："+getOnlineCount());
        }

    }

    /**
     * 获取Channel绑定信息
     * @param channel
     * @return
     */
    public NettyAttributeMapDTO getAttribute(Channel channel)
    {
        Attribute<NettyAttributeMapDTO> attr = channel.attr(NETTY_CHANNEL_KEY);
        NettyAttributeMapDTO attribute = attr.get();
        return attribute;
    }
}
